package com.aokang.footwear.common.config.mp;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ReflectUtil;
import com.aokang.footwear.common.utils.MyDateUtil;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.chiyoyo.tokenhelper.TokenHelper;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.time.LocalDateTime;

/**
 * mybatisPlus之自动填充工具
 *
 * @author chilei
 */
@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

    @Override
    public void insertFill(MetaObject metaObject) {
        LocalDateTime now = LocalDateTime.now();
        String userid = TokenHelper.getUserid();
        setDefaultFieldValue(metaObject, "createDate", now, FieldFill.INSERT);
        setDefaultFieldValue(metaObject, "createTime", now, FieldFill.INSERT);
        setDefaultFieldValue(metaObject, "createAt", now, FieldFill.INSERT);
        setDefaultFieldValue(metaObject, "createBy", userid, FieldFill.INSERT);
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        LocalDateTime now = LocalDateTime.now();
        String userid = TokenHelper.getUserid();
        setDefaultFieldValue(metaObject, "updateDate", now, FieldFill.UPDATE);
        setDefaultFieldValue(metaObject, "updateTime", now, FieldFill.UPDATE);
        setDefaultFieldValue(metaObject, "updateAt", now, FieldFill.UPDATE);
        setDefaultFieldValue(metaObject, "updateBy", userid, FieldFill.UPDATE);
    }

    /**
     * 在 MetaObject 中为指定字段设置默认值。
     *
     * @param metaObject   MyBatis-Plus 的元对象，代表当前操作的实体对象。
     * @param fieldName    需要设置默认值的字段名称。
     * @param defaultValue 默认值，当字段未被初始化时使用。
     * @param fieldFill    填充策略，决定何时填充字段值，如插入前、更新前等。
     */
    private void setDefaultFieldValue(MetaObject metaObject, String fieldName, Object defaultValue, FieldFill fieldFill) {
        try {
            // 检查字段当前是否已有值
            if (getFieldValByName(fieldName, metaObject) != null) {
                return;
            }

            Field field = ReflectUtil.getField(metaObject.getOriginalObject().getClass(), fieldName);
            if (shouldFillField(field, fieldFill)) {
                Object convertedValue = convertValueToFieldType(field.getType(), defaultValue);
                setFieldValByName(fieldName, convertedValue, metaObject);
            }
        } catch (Exception e) {
            log.error("mybatis-plus 设置字段默认值失败, 不影响业务运行", e);
        }
    }

    /**
     * 判断字段是否需要填充
     */
    private boolean shouldFillField(Field field, FieldFill fieldFill) {
        return field != null && field.isAnnotationPresent(TableField.class)
                && field.getAnnotation(TableField.class).fill() == fieldFill;
    }

    /**
     * 转换默认值到字段的类型
     */
    private Object convertValueToFieldType(Class<?> fieldType, Object defaultValue) {
        if (defaultValue == null) {
            return null;
        }

        if (fieldType.equals(String.class) && defaultValue instanceof LocalDateTime) {
            return ((LocalDateTime) defaultValue).format(MyDateUtil.Y_MM_DD_HH_MM_SS);
        }
        return Convert.convert(fieldType, defaultValue);
    }
}
